home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i076: An electronic office sign-in/signout pegboard
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Richard O'Rourke <uunet!mplex!ror>
- Posting-number: Volume 20, Issue 76
- Archive-name: pegboard
-
- [ I tweaked the Makefile and added the -DBSD stuff; looks like the
- original was for Xenix (/etc/default?) /r$ ]
-
- This program can be used to keep track of who is in or out of the
- office, and when they are due back. To be useful, people have to
- USE it, but this is true of traditional pegboards as well. People
- here find it friendly enough and pretty much keep the pegboard updated.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: Makefile README default.peg dot.pegrc peg.h peg.h.ansi
- # peg.man peg.y pegboard.hdr pegio.c tfix.c
- # Wrapped by rsalz@prune.bbn.com on Fri Oct 27 13:08:48 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(477 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XOBJS = peg.o tfix.o pegio.o
- XSRCS = peg.c tfix.c pegio.c
- XBINDIR = /usr/lbin
- X
- X#DEFS=-DBSD -DLPNMAX=128
- XOPTS = -O $(DEFS)
- X#
- X# Name of executable
- XBNAME = peg
- X
- X$(BNAME): $(OBJS) peg.h
- X cc $(OPTS) -o $(BNAME) $(OBJS)
- X
- Xpeg.o: peg.c peg.h
- X cc $(OPTS) -c peg.c
- X
- Xtfix.o: tfix.c peg.h
- X cc $(OPTS) -c tfix.c
- X
- Xpegio.o: pegio.c peg.h
- X cc $(OPTS) -c pegio.c
- X
- Xclean:
- X rm $(OBJS)
- Xinstall:
- X mv peg $(BINDIR)/peg
- X mv default.peg /etc/default/peg
- Xlint:
- X lint -pubx $(SRCS) >lint.out
- X
- Xpeg.c: peg.y
- END_OF_FILE
- if test 477 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1460 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XPeg is an online pegboard. It is used to see if someone is in or
- Xout of the office and when they are expected back. Do "make install"
- Xafter you get it to compile.
- X
- XThere is at least 1 incompatibilty problem you may encounter, fcntl
- Xtype locking is used. The functions are "pblock()" and "pbunlock()"
- Xin "pegio.c". "getopts()" is required, if you don't have it you can
- Xget it from an archive site. You will want yacc if you are going to
- Xdo any major additions to the source. There is nothing in the makefile
- Xto install the man page, you will have to do that by hand.
- X
- XYou may find it useful for other things too, the verify "-v" option
- Xhas possibilities, eg.:
- X--------
- X#
- X# Mail list of meeting dates and times to users
- X#
- XSDATE="Monday 8" # The first meeting, next Monday at 8:00A
- XUSERLIST=administrators
- XSUBJECT=Meetings
- XMESSAGE="Future meeting dates and times, please don't be late:\n"
- X
- X{
- X echo $MESSAGE
- X #
- X # 6 monthly meetings, each on the day given in SDATE
- X for OFFSET in 0 4 8 12 16 20
- X do
- X peg -v $SDATE + ${OFFSET}w
- X done
- X} | mail -s $SUBJECT $USERLIST
- X--------
- X
- XPeg needs some way of recognizing dates that are holidays, so they can
- Xbe skipped when the "-t" option is given. This is not covered in the
- Xcurrent implementation. If someone cares to add this feature please
- Xsend us the additions.
- X
- XThis was my first bout with yacc, and I'm sure there are better ways
- Xto do what I did. Constructive criticism is welcome, send to:
- X
- Xuunet!mplex!ror
- END_OF_FILE
- if test 1460 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'default.peg' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'default.peg'\"
- else
- echo shar: Extracting \"'default.peg'\" \(165 characters\)
- sed "s/^X//" >'default.peg' <<'END_OF_FILE'
- X#
- X# NOUNPEG for a given tty will result in users NOT being unpegged
- X# when they log on via that tty. Useful for modem lines.
- X
- X#NOUNPEG /dev/tty1A
- XPEGDIR=/usr/spool
- END_OF_FILE
- if test 165 -ne `wc -c <'default.peg'`; then
- echo shar: \"'default.peg'\" unpacked with wrong size!
- fi
- # end of 'default.peg'
- fi
- if test -f 'dot.pegrc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dot.pegrc'\"
- else
- echo shar: Extracting \"'dot.pegrc'\" \(57 characters\)
- sed "s/^X//" >'dot.pegrc' <<'END_OF_FILE'
- Xmon 8:30
- Xtue 8:30
- Xwed 8:30
- Xthu 8:30
- Xfri 8:30
- Xsat -
- Xsun -
- END_OF_FILE
- if test 57 -ne `wc -c <'dot.pegrc'`; then
- echo shar: \"'dot.pegrc'\" unpacked with wrong size!
- fi
- # end of 'dot.pegrc'
- fi
- if test -f 'peg.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'peg.h'\"
- else
- echo shar: Extracting \"'peg.h'\" \(1322 characters\)
- sed "s/^X//" >'peg.h' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <string.h>
- X#include <pwd.h>
- X#include <time.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#include <ctype.h>
- X#include <errno.h>
- X
- X#define HOMENV "HOME"
- X#define PEGRCFN ".pegrc"
- X#define PBFNM "pegboard"
- X#define RCFNAM "/etc/default/peg"
- X
- X#define PBDIR "/usr/spool"
- X#define TMPLATE "PEGCOPY.XXXXXX"
- X#define PEGBOARD "/usr/spool/pegboard"
- X#define PEGLOCK "/tmp/LCK.pegboard"
- X#define OKCS \
- X " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ +,~@0123456789"
- X
- Xtypedef void int;
- X
- Xvoid use ( );
- Xvoid copytime( );
- Xvoid dround ( );
- Xvoid faterr ( );
- Xvoid finit ( );
- Xvoid specerr ( );
- Xchar *igets ( );
- Xchar *lows ( );
- Xchar *getenv ( );
- Xchar *ttyname( );
- Xchar *fixargs( );
- Xchar *malloc ( );
- Xchar *mktemp ( );
- Xint cleanup ( );
- Xint chkpeg ( );
- Xlong fixstrt ( );
- Xlong fixday ( );
- Xlong fixday ( );
- Xlong fixhm ( );
- Xlong fixymd ( );
- Xlong time ( );
- Xlong lseek ( );
- Xstruct passwd *getpwuid( );
- Xstruct passwd *getpwnam( );
- Xstruct tm *localtime ( );
- X
- Xextern int opterr;
- Xextern int optind;
- Xextern int eod;
- Xextern int admupd;
- Xextern int quiet;
- Xextern int vrbose;
- Xextern int normpeg;
- Xextern char lb[];
- Xextern char *invkst;
- Xextern char *pegfnm;
- Xextern char *pegdir;
- Xextern char *optarg;
- Xextern char *sys_errlist[];
- Xextern int sys_nerr;
- Xextern int errno;
- Xextern long duback;
- Xextern long starts[];
- Xextern struct tm today;
- X
- END_OF_FILE
- if test 1322 -ne `wc -c <'peg.h'`; then
- echo shar: \"'peg.h'\" unpacked with wrong size!
- fi
- # end of 'peg.h'
- fi
- if test -f 'peg.h.ansi' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'peg.h.ansi'\"
- else
- echo shar: Extracting \"'peg.h.ansi'\" \(1500 characters\)
- sed "s/^X//" >'peg.h.ansi' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <string.h>
- X#include <pwd.h>
- X#include <time.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#include <ctype.h>
- X#include <errno.h>
- X
- X#define HOMENV "HOME"
- X#define PEGRCFN ".pegrc"
- X#define PBFNM "pegboard"
- X#define RCFNAM "/etc/default/peg"
- X
- X#define PBDIR "/usr/spool"
- X#define TMPLATE "PEGCOPY.XXXXXX"
- X#define PEGBOARD "/usr/spool/pegboard"
- X#define PEGLOCK "/tmp/LCK.pegboard"
- X#define OKCS " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\
- X+,~@0123456789"
- X
- Xvoid use ( );
- Xvoid copytime( );
- Xvoid dround ( long * );
- Xvoid faterr ( char * );
- Xvoid finit ( FILE *, char *[] );
- Xvoid specerr ( char * );
- Xchar *igets ( char [], int, int );
- Xchar *lows ( char * );
- Xchar *getenv ( char * );
- Xchar *ttyname( int );
- Xchar *fixargs( char *[] );
- Xchar *malloc ( unsigned );
- Xchar *mktemp ( char * );
- Xint cleanup ( );
- Xint chkpeg ( unsigned short );
- Xlong fixstrt ( char * );
- Xlong fixday ( long );
- Xlong fixday ( long );
- Xlong fixhm ( long, long );
- Xlong fixymd ( long, long, long );
- Xlong time ( long * );
- Xlong lseek ( int, long, int );
- Xstruct passwd *getpwuid( int );
- Xstruct passwd *getpwnam( char * );
- Xstruct tm *localtime ( long * );
- X
- Xextern int opterr;
- Xextern int optind;
- Xextern int eod;
- Xextern int admupd;
- Xextern int quiet;
- Xextern int vrbose;
- Xextern int normpeg;
- Xextern char lb[];
- Xextern char *invkst;
- Xextern char *pegfnm;
- Xextern char *pegdir;
- Xextern char *optarg;
- Xextern char *sys_errlist[];
- Xextern int sys_nerr;
- Xextern int errno;
- Xextern long duback;
- Xextern long starts[];
- Xextern struct tm today;
- X
- END_OF_FILE
- if test 1500 -ne `wc -c <'peg.h.ansi'`; then
- echo shar: \"'peg.h.ansi'\" unpacked with wrong size!
- fi
- # end of 'peg.h.ansi'
- fi
- if test -f 'peg.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'peg.man'\"
- else
- echo shar: Extracting \"'peg.man'\" \(7450 characters\)
- sed "s/^X//" >'peg.man' <<'END_OF_FILE'
- X.tr _
- X.TH PEG 1 "mplex"
- X.SH NAME
- X.I "peg"
- X\- pegboard system
- X.SH SYNTAX
- X.RB peg
- X[\-u|i
- X.I user
- X]
- X[\-c
- X.I text
- X] [-lnqtvx] [+N[m|h|d|w] [H[:[M]][p]] [[[Y]/M]/D] [day] [month mday]
- X.SH OPTIONS
- X.TP 12
- X.BR \-q
- Xsuppress heading when reporting, suppress printing of date when updating
- X.TP
- X.BR \-u user
- Xprint specific user's pegboard entry
- X.TP
- X.BR \-i user
- X(interrogate) returns a value of 0 if the user is on the pegboard, 1 if not
- X.TP
- X.BR \-c text
- Xmay be used to add a comment that is printed with the pegboard
- X.TP
- X.BR \-t
- XLog off until tomorrow.
- XThe file ".pegrc" in the invoking users home directory is consulted
- Xto get the time of day the user starts work.
- X.TP
- X.BR \-v
- XVerify only, with this option the time and date arguments are parsed and
- Xthe target time is printed.
- XThe pegboard is
- X.B not
- Xupdated nor is the invoker logged off.
- X.TP
- X.BR \-x
- XRemove the invoking users peg.
- XIt is not desirable for this option to work when
- X.I peg
- Xis invoked from
- Xcertain ttys, specifically modems and some network ports.
- XThis situation occurs when "peg -x" is put in the system
- X.I .profile,
- X(or equivalent) and a user dials in on a modem port.
- XA facility is provided to avoid this in the file
- X.I /etc/default/peg
- X( see
- X.BR FILES
- Xheading below).
- X.TP
- X.BR \-n
- Xdon't log off after updating pegboard
- X.TP
- X.BR \-l
- XPrints long format
- X.SH DESCRIPTION
- X.I peg
- Xmaintains a list of users who have logged off the system (a
- X.I pegboard
- X), and dates and times of when they intend return to the site.
- XThe default action when no arguments are given is to print the
- Xpegboard contents on standard output.
- XThe -u option may be used to print the pegboard entry for a
- Xspecific user.
- X.P
- XContext of arguments is dependent on their format.
- XArguments that contain a "/" character are taken to be a date,
- Xand one or two "/"'s may be present.
- XIn the case of one, "MM/DD" is taken as a month and a day.
- X"YY/MM/DD" is taken as year month and day.
- X.P
- XArguments that contain a ":" are taken as a time, and only one
- X":" may be present.
- X"HH:MM" is taken as hour and minute.
- XA single argument is taken to be an hour in the current day.
- XHours are in 24 hour format, unless the argument is suffixed with the
- Xletter "p", in which case the time is assumed to be after 12 noon.
- XFinally, a full date and time specification may be given by
- Xproviding both arguments, in either order.
- X.P
- XNumeric arguments may be preceded by a "+", in this case
- Xthe argument is taken as a "relative" quantity of time.
- XThere may be an optional modifier after relative arguments,
- Xlegal modifiers are "m", "h", "d" and "w".
- X.TP
- X.BR m
- Xthe offset is taken as a number of minutes from the current time
- X.TP
- X.BR h
- Xthe offset is taken as a number of hours from the current time (default)
- X.TP
- X.BR d
- Xthe offset is taken as a number of days from the current date
- X.TP
- X.BR w
- Xthe offset is taken as a number of weeks from the current date
- X.P
- XIf a modifier is not given and the argument is in "+n" format,
- X"n" is assumed to be a number of hours from the current time
- X(the h modifier is redundant).
- X.P
- XPeg recognizes names of days and months as well.
- XMonth names must be followed by a day, ie. Sept 12.
- XThe next occurrence of a day or month/day combination specified is assumed.
- XSo specifying Tue on a Wednesday results in Tuesday of next week being
- Xthe specified day.
- XSimilarly, giving a month/day that has already gone by results in that day
- Xin the next year being the specified date.
- X.P
- XAny (reasonable) number of arguments may be given.
- XThe effect of multiple arguments is additive, so specifying more
- Xthan one absolute date or time will not likely yield expected results.
- XMixing one absolute date with some number of relative type arguments
- Xhas the effect of adding the relative arguments to the absolute.
- X.P
- XAfter the pegboard is updated (and the -n, -x, -i or -v options
- Xwere not given),
- Xall processes in the process group are sent the signal SIGKILL.
- X.P
- X.I "peg"
- Xshould be run with the "-x" option in the system
- X.I .profile
- Xso that each time the a user logs onto the system their pegboard entry
- Xis expunged.
- X.P
- X.SH EXAMPLES
- X.TP 20
- X.BR "peg 99/1/12 14:00"
- XLog off and peg invoking user to be back January 12, 1999, at 2:00 pm
- X.TP 20
- X.BR "peg 2:00p 99/1/12"
- XSame as above
- X.TP 20
- X.BR "peg 3/10"
- XLog off and peg invoking user to be back March 10 at the current time.
- XIf March 10th has passed then March 10th next year is assumed.
- X.TP 20
- X.BR "peg +2"
- XLog off and peg invoking user to be back 2 hours from current time
- X.TP 20
- X.BR "peg 2:00p"
- XLog off and peg invoking user to be back at 2pm today
- X.TP 20
- X.BR "peg +45m"
- XLog off and peg invoking user to be back 45 minutes from the current time
- X.TP 20
- X.BR "peg -t +3d"
- XLog off and peg invoking user to be back 3 days from current date at the
- Xtime found in the ".pegrc" file in their home directory
- X.TP 20
- X.BR "peg -t"
- XLog off and and peg invoking user to be back on the next day and time that has
- Xan entry in the ".pegrc" file.
- XDays that have no entry will be skipped over.
- X.TP 20
- X.BR "peg -t 14"
- XLog off and peg invoking user to be back 2:00 pm on the next day specified
- Xin their
- X.I .pegrc
- Xfile.
- X.TP 20
- X.BR "peg -v +1 +1 +1"
- Xprint what time it will be in three hours
- X.P
- X.SH FILES
- X.TP
- X.BR /etc/default/peg
- X.TP
- X.BR /$HOME/.pegrc
- XThese files may have default start times for users in the format:
- X.P
- X.nf
- X.sp
- XMON 8:00
- X.sp .5
- XTUE 8:00
- X.sp .5
- X .
- X.sp .5
- X .
- X.sp .5
- X .
- X.sp .5
- XFRI 8:00
- XSAT -
- X.sp .5
- XSUN -
- X.fi
- X.P
- XIn addition,
- X.I "/etc/default/peg"
- Xshould contain entries of these formats:
- X.P
- X.nf
- XPEGDIR /usr/spool
- X.fi
- X.P
- XThis variable specifies the directory that peg uses for the pegboard.
- XEach machine associated with a common pegboard should have
- Xan "/etc/default/peg" file, specifying a common directory in
- Xthe PEGDIR variable.
- XThe pegbord file in the common directory must be readable and writable
- Xby all users.
- X.P
- X.nf
- X.sp .5
- XNOUNPEG /dev/ttyxx
- X.fi
- X.P
- X.P
- XUsed to specify tty's that override the action of the
- X.I "-x"
- Xoption.
- XIf peg is invoked from a tty that is listed thusly in
- X.I "/etc/default/peg"
- Xthen the program exits without updating the pegboard.
- XPorts that are connected to modems should be listed in this manner.
- X.TP 24
- X.BR PEGDIR/pegboard.a*
- Xholds a copy of the pegboard when update is in progress
- X.TP 24
- X.BR $HOME/.pegrc
- Xdefault start time of day and days of week
- X.TP 24
- X.BR /etc/passwd
- XUsernames etc. are extracted from this file.
- XThe users name is assumed to be in the "gecos" field of the passwd entry
- X.SH NOTES
- XThe pegboard is maintained using
- X.I "user id"
- Xnumbers.
- X.P
- XOnly the first 3 letters of day and month names are significant.
- X.P
- XIf the real user id of the invoking user is 0 and the
- X.I "-u"
- Xcommand line option
- Xis given then the specified users pegboard entry is updated to the date
- Xgiven.
- XIf the invoking user id is 0 and both the
- X.I "-u"
- Xand
- X.I "-x"
- Xoptions are given then the user name specified as the
- X.I "-u"
- Xargument is removed from the pegboard.
- X.P
- XWeek and month names etc. in the command line and tokens and variable names
- Xin the
- X.I ".pegrc"
- Xand
- X.I "/etc/default/peg"
- Xfiles are
- X.BR not
- Xcase sensitive.
- X.I Arguments
- Xin the
- X.I /etc/default/peg
- Xand
- X.I .pegrc
- Xfiles
- X.BR are
- Xcase sensitive.
- X.P
- XComments are restricted to 64 characters, and must be whitespace or printable.
- XThey are truncated to 32 characters in the short form to avoid
- Xmessing up screens (assuming 80 column ttys).
- XThe complete comment may be read by invoking with the "-l" option.
- X.P
- XIf no PEGDIR variable is found in the
- X.I /etc/default/peg
- Xfile then the default directory used is
- X.I /usr/spool.
- X
- END_OF_FILE
- if test 7450 -ne `wc -c <'peg.man'`; then
- echo shar: \"'peg.man'\" unpacked with wrong size!
- fi
- # end of 'peg.man'
- fi
- if test -f 'peg.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'peg.y'\"
- else
- echo shar: Extracting \"'peg.y'\" \(7896 characters\)
- sed "s/^X//" >'peg.y' <<'END_OF_FILE'
- X%{
- X/*
- X peg.y
- X
- X Copyright 1989 RFM Microplex Systems Ltd.
- X RFM Microplex Systems Ltd.
- X 265 E. 1st Ave.
- X Vancouver, B.C. CANADA
- X V5T 1A7
- X (604)875-1461
- X Fax: (604)875-9029
- X Email: uunet!mplex!ror
- X
- X These documents are copyrighted. However, they may be distributed freely
- X as long as the following is understood and followed:
- X
- X A; They may not be distributed for financial or other gain under any
- X circumstances.
- X B; The author(s) and RFM Microplex Systems Ltd. will not be held liable
- X for any damage or loss of data arising from their use
- X C; Anyone who applies improvements or "bug fixes" shall make an attempt
- X to return these changes to the author listed above
- X D. This copyright applies to all of the documents listed below, and any
- X other information created by compilers or other programs that are
- X applied to them:
- X peg.man peg.y tfix.c peg.h pegio.c
- X*/
- X#include "peg.h"
- X
- X#define YYSTYPE long
- X
- Xchar *invkst; /* Name of the executable */
- Xchar *pegdir; /* Directory name for various files */
- Xchar *pegfnm; /* File name where pegs go */
- Xchar *comment; /* User's reason for leaving, if given */
- Xchar lb[BUFSIZ]; /* Lines for yylex */
- Xint chk; /* Check run only */
- Xint eod; /* Log off till tomorrow */
- Xint admupd; /* Administrator updating mortals peg */
- Xint quiet; /* No header, don't print time when done */
- Xint vrbse; /* Verbose output (this is not the opposite of quiet) */
- Xint normpeg; /* Set if login tty is on no pegout list */
- X/*
- X Start times for invoking user stored here by rcinit
- X*/
- Xlong starts [] = { -1, -1, -1, -1, -1, -1, -1 };
- Xlong int duback; /* Running count in seconds of the date determined */
- Xstruct tm today; /* */
- Xstruct tm *s;
- X%}
- X%token NUMBER
- X%right ':'
- X%left '+'
- X%right '/'
- X%right 'p'
- X%%
- Xnothing:
- X | nothing expr
- X ;
- Xexpr: NUMBER {
- X $$ = fixhm( $1, 0L );
- X }
- X | NUMBER ':' NUMBER {
- X $$ = fixhm( $1, $3 );
- X }
- X | NUMBER ':' NUMBER 'p' {
- X $$ = fixhm( $1 < 12 ? $1 + 12 : $1 , $3 );
- X }
- X | NUMBER '/' NUMBER {
- X $$ = fixymd(
- X (( $1 < today.tm_mon + 1 ||
- X ( $1 == today.tm_mon + 1 && $3 < today.tm_mday ))
- X ? (long)today.tm_year + 1 : (long)today.tm_year ), $1 , $3 );
- X }
- X | NUMBER '/' NUMBER '/' NUMBER {
- X $$ = fixymd( $1, $3 , $5 );
- X }
- X | NUMBER 'p' {
- X $$ = fixhm( $1 < 12 ? $1 + 12 : $1 , 0L );
- X }
- X
- X | '+' NUMBER {
- X s = localtime( &duback );
- X $$ = fixhm( (long)s->tm_hour + $2, (long)s->tm_min );
- X }
- X | '+' NUMBER 'h' {
- X s = localtime( &duback );
- X $$ = fixhm( (long)s->tm_hour + $2, (long)s->tm_min );
- X }
- X | '+' NUMBER 'm' {
- X s = localtime( &duback );
- X $$ = fixhm( (long)s->tm_hour, (long)s->tm_min + $2 );
- X }
- X | '+' NUMBER 'd' {
- X $$ = fixday( $2 );
- X }
- X | '+' NUMBER 'w' {
- X $$ = fixday( $2 * 7L );
- X }
- X ;
- X%%
- X/*
- X BUGS TO FIX:
- X none (ha)
- X*/
- X
- Xmain( argc, argv )
- Xint argc;
- Xchar *argv[];
- X{
- X extern struct tm today;
- X extern long duback;
- X extern char lb[];
- X extern char *pegfnm;
- X extern char *pegdir;
- X extern char *invkst;
- X extern char *optarg;
- X extern char *sys_errlist[];
- X extern int sys_nerr;
- X extern int errno;
- X extern int eod;
- X extern int vrbse;
- X extern int admupd;
- X struct passwd *rpu = NULL;
- X int i;
- X int exp = 0;
- X extern int chk;
- X extern int normpeg;
- X int logout = 1;
- X
- X invkst = (( strrchr( argv[0], '/' ) == NULL )
- X ? argv[0] : strrchr( argv[0], '/' ) + 1 );
- X /*
- X Read "rc" files
- X */
- X pegfnm = NULL;
- X comment = NULL;
- X pegdir = NULL;
- X rcinit( );
- X
- X# define LGLOPTS "c:i:u:lnqtvx"
- X opterr=0;
- X while(( i = getopt( argc, argv, LGLOPTS )) != EOF ) {
- X switch( i ) {
- X /*
- X Suppress start time rounding
- X */
- X case 't':
- X eod++;
- X break;
- X /*
- X Peg invoking user as back at site (delete pegboard entry)
- X */
- X case 'x':
- X exp++;
- X break;
- X /*
- X Report due back date for specified userm unless invoker
- X is root. If root then diddle other users peg
- X */
- X case 'u':
- X if( ! getuid( )) {
- X if( setuid( getpwnam( optarg )->pw_uid ))
- X faterr( "setuid call failed" );
- X admupd++;
- X break;
- X }
- X if(( rpu = getpwnam( optarg )) == NULL )
- X fprintf( stderr,
- X "\n%s: user \"%.*s\" not found\n",
- X invkst, strspn( optarg, OKCS ), optarg );
- X break;
- X /*
- X Don't log the user off after updtaing pegboard
- X */
- X case 'n':
- X logout = 0;
- X break;
- X /*
- X Supress printing of header and time
- X */
- X case 'q':
- X quiet = ( ! quiet );
- X break;
- X /*
- X Check run only, no update, no logout
- X */
- X case 'v':
- X chk++;
- X break;
- X /*
- X Print long format
- X */
- X case 'l':
- X vrbse++;
- X break;
- X /*
- X Read comment
- X */
- X case 'c':
- X comment = ( strlen( optarg ) > BUFSIZ ? "" : optarg );
- X break;
- X /*
- X Interrogate pegboard. Return 0 if invoker pegged.
- X */
- X case 'i':
- X if( ! *optarg )
- X exit( 1 );
- X exit( chkpeg( getpwnam( optarg )->pw_uid ));
- X
- X case '?':
- X default:
- X fprintf( stderr,
- X "\n%s: Unrecognized option \"%c\"\n",
- X invkst, i );
- X use( ); /* Exits */
- X } /* End of switch */
- X } /* End of while */
- X
- X if( ! normpeg && exp ) {
- X upddbdf( getuid( ), 1 );
- X exit( 0 );
- X }
- X if ( exp )
- X exit( 0 );
- X
- X /* Report for specific user */
- X if( rpu != NULL) {
- X report( rpu->pw_uid, quiet );
- X exit( 0 );
- X }
- X
- X if((( argc - optind ) < 1 ) && ( ! eod )) {
- X /* No arguments, report all pegged users */
- X report( 0, quiet );
- X exit( 0 );
- X }
- X
- X lb[0] = '\0';
- X fixargs( &argv[optind] );
- X if(( ! lb[0] ) && eod )
- X sprintf( lb, "+1d" );
- X time( &duback );
- X copytime( localtime( &duback ), &today );
- X
- X yyparse( );
- X
- X if( chk ) {
- X showtime( &duback );
- X exit( 0 );
- X }
- X /*
- X Update the pegboard. If it fails then don't die.
- X */
- X if( upddbdf( getuid( ), 0 ))
- X logout = 0;
- X /*
- X Don't die if root
- X */
- X if( ! getuid( ) || admupd )
- X exit( 0 );
- X
- X if( logout )
- X kill( -1, SIGKILL );
- X exit( 0 );
- X}
- X
- Xyylex( )
- X{
- X static char *lp;
- X static int init=1;
- X char copy[ BUFSIZ ];
- X int lah1;
- X int lah2;
- X extern char lb[];
- X
- X if( init ) {
- X init=( ! init );
- X lp = lb;
- X }
- X
- X while( *lp == ' ' || *lp == '\t' )
- X lp++;
- X if( ! *lp || *lp == '\n' )
- X return( 0 );
- X if( isdigit( *lp )) {
- X sscanf( lp, "%ld", &yylval );
- X lp = ( lp + strspn( lp, "0123456789" ));
- X return( NUMBER );
- X }
- X /*
- X Look for a literal month name and day number
- X */
- X if(( lah1 = ismonth( lp ))) {
- X do {
- X if( ! *lp++ )
- X specerr( "month name must be followed by day of month" );
- X } while ( ! isdigit( *lp ));
- X
- X sscanf( lp, "%d", &lah2 );
- X
- X lp = strpbrk( lp, " \t\n" ); /* SP, TAB, NL */
- X strcpy( copy, lp ); /* If this is NULL that's exactly what we want */
- X if(( lah1 - 1 ) < today.tm_mon ||
- X (( lah1 - 1 ) == today.tm_mon && lah2 < today.tm_mday ))
- X sprintf( lp, "%d/%d/%d %s", today.tm_year + 1, lah1, lah2, copy );
- X else
- X sprintf( lp, "%d/%d/%d %s", today.tm_year, lah1, lah2, copy );
- X sscanf( lp, "%ld", &yylval );
- X lp = strchr( lp, '/' );
- X return( NUMBER );
- X }
- X if(( lah1 = isday( lp )) != (-1)) {
- X lp = strpbrk( lp, " \t\n" ); /* SP, TAB, NL */
- X strcpy( copy, lp ); /* If this is NULL that's exactly what we want */
- X if( lah1 < today.tm_wday )
- X lah1 += 7;
- X lah1 -= today.tm_wday;
- X sprintf( lp, "+%dd %s", lah1, copy );
- X }
- X return( (int)*lp++ );
- X}
- X
- X/*
- X Consolidate string list
- X*/
- Xchar *fixargs( ss )
- Xchar **ss;
- X{
- X extern char lb[];
- X
- X while( **ss ) {
- X strcat( lb, *ss++ );
- X if(( strlen( lb )) >= BUFSIZ )
- X specerr( "argument string to long" );
- X strcat( lb, " " );
- X }
- X return( lows( lb ));
- X}
- X
- X/*
- X Make s lowercase.
- X*/
- Xchar *lows( s )
- Xchar *s;
- X{
- X int i;
- X
- X for( i = 0 ; s[i] ; i++ )
- X s[i] = tolower( s[i] );
- X return( s );
- X}
- X
- Xyyerror( m )
- Xchar *m;
- X{
- X specerr(m);
- X}
- X
- Xvoid specerr( m )
- Xchar *m;
- X{
- X extern char *invkst;
- X
- X fprintf( stderr,
- X "\n%s: Bad specification (%.*s)\n",
- X invkst, strspn( m, OKCS ), m );
- X use( );
- X}
- X
- Xvoid use( s )
- Xchar *s;
- X{
- X extern char *invkst;
- X
- X /* LGLOPTS "tc:xu:vnqli:" */
- X fprintf( stderr,
- X "\n%s: maintains an \"on-line pegboard\"\n", invkst );
- X fprintf( stderr,
- X "use: %s [-u|i user -c \"comment\" [-qnxtvl] [date time]\n", invkst );
- X
- X exit( 1 );
- X}
- END_OF_FILE
- if test 7896 -ne `wc -c <'peg.y'`; then
- echo shar: \"'peg.y'\" unpacked with wrong size!
- fi
- # end of 'peg.y'
- fi
- if test -f 'pegboard.hdr' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pegboard.hdr'\"
- else
- echo shar: Extracting \"'pegboard.hdr'\" \(1020 characters\)
- sed "s/^X//" >'pegboard.hdr' <<'END_OF_FILE'
- XFrom mplex!ror@uunet.uu.net Tue Apr 18 12:57:54 1989
- XReceived: from BBN.COM by pineapple.bbn.com
- X id <AA01790@pineapple.bbn.com>; Tue, 18 Apr 89 12:56:01 -0400
- XReceived: from uunet.uu.net by BBN.COM id aa02889; 15 Apr 89 3:21 EDT
- XReceived: from mplex.UUCP by uunet.UU.NET (5.61/1.14) with UUCP
- X id AA08484; Sat, 15 Apr 89 03:31:02 -0400
- XFrom: mplex!ror@uunet.UU.NET
- XMessage-Id: <8904150731.AA08484@uunet.UU.NET>
- XTo: uunet!comp-sources-unix@uunet.UU.NET
- XDate: Fri Apr 14 11:55:23 1989
- XStatus: R
- X
- XTo: uunet!comp-sources-unix
- XPath: mplex!ror
- XFrom: ror@mplex.UUCP (Richard O'Rourke)
- XNewsgroups: comp.sources.unix
- XSubject: Online Pegboard
- XMessage-ID: <271@mplex.UUCP>
- XDate: 14 Apr 89 19:55:11 GMT
- XOrganization: RFM Microplex Systems Ltd.
- XLines: 2655
- X
- X
- XThis program can be used to keep track of who is in or out of the
- Xoffice, and when they are due back. To be useful, people have to
- XUSE it, but this is true of traditional pegboards as well. People
- Xhere find it friendly enough and pretty much keep the pegboard updated.
- X
- END_OF_FILE
- if test 1020 -ne `wc -c <'pegboard.hdr'`; then
- echo shar: \"'pegboard.hdr'\" unpacked with wrong size!
- fi
- # end of 'pegboard.hdr'
- fi
- if test -f 'pegio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pegio.c'\"
- else
- echo shar: Extracting \"'pegio.c'\" \(10884 characters\)
- sed "s/^X//" >'pegio.c' <<'END_OF_FILE'
- X/*
- X pegio.c
- X*/
- X
- X#include "peg.h"
- X
- X#define HEADER "User Due Back Comment"
- X#define VHEADER "User Logged Off Due Back Name"
- X
- X/*
- X Report pegboard for 1 or all users. Call with user number 0 to
- X get them all.
- X
- X*/
- Xreport( who, nohdr )
- Xint who; /* User number */
- Xint nohdr; /* Quiet */
- X{
- X extern char *pegfnm;
- X extern int vrbse;
- X
- X static char *months [] = {
- X "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" };
- X static char *days [] = {
- X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- X
- X FILE *pegfd;
- X char tb[BUFSIZ+1];
- X char cb[BUFSIZ+1];
- X long tlo;
- X long tdb;
- X int u;
- X struct tm *j;
- X struct passwd *p;
- X
- X if( ! nohdr )
- X puts( vrbse ? VHEADER : HEADER );
- X if(( pegfd = fopen( pegfnm, "r" )) == NULL ) {
- X if( errno == ENOENT )
- X exit( 0 );
- X sprintf( tb,
- X "Cannot read pegboard file \"%s\"", pegfnm );
- X faterr( tb ); /* Exits. */
- X }
- X
- X while(( fgets( tb, BUFSIZ, pegfd )) != NULL) {
- X cb[0] = '\0';
- X sscanf( tb, "%d %ld %ld %64[ -~\t]\n", &u, &tlo, &tdb, cb );
- X
- X if(( ! who ) || who == u ) {
- X p = getpwuid( u );
- X
- X if( vrbse) {
- X j = localtime( &tlo );
- X printf( "%-7.8s %3s %3s %2d %2d:%02d ",
- X p->pw_name,
- X days[j->tm_wday], months[j->tm_mon],
- X j->tm_mday, j->tm_hour, j->tm_min );
- X j = localtime( &tdb );
- X printf( "%3s %3s %2d %2d:%02d %02d %.24s\n",
- X days[j->tm_wday], months[j->tm_mon],
- X j->tm_mday, j->tm_hour, j->tm_min, j->tm_year,
- X p->pw_gecos );
- X if( cb[0] )
- X printf(
- X " %.64s\n",
- X cb);
- X }
- X else {
- X j = localtime( &tdb );
- X printf( "%-24.25s %3s %3s %2d %2d:%02d %02d %.32s\n",
- X p->pw_gecos,
- X days[j->tm_wday], months[j->tm_mon],
- X j->tm_mday, j->tm_hour, j->tm_min, j->tm_year, cb );
- X }
- X
- X if( setpwent( ) == EOF )
- X faterr( "cannot reset password file" ); /* Exits. */
- X }
- X endpwent( );
- X }
- X fclose( pegfd );
- X}
- X
- X/*
- X Update the pegboard. Dates gone by do not have the associated
- X entry deleted but if x is 0 then the users entry is expunged.
- X*/
- Xupddbdf( ru, x )
- Xint ru; /* User number *.
- Xint x; /* Delete peg flag */
- X{
- X extern struct tm today;
- X extern char *invkst;
- X extern char *pegfnm;
- X extern char *comment;
- X extern int eod; /* Round off to the start of day found in rc */
- X extern int admupd; /* Administrator updating mortals peg */
- X extern int quiet; /* Supresses printing of time when done */
- X extern long duback;
- X extern long starts[];
- X
- X extern int cleanup( );
- X int ( *clnp )( );
- X int pegfd;
- X int clfd;
- X FILE *tfp;
- X char tb[BUFSIZ+1];
- X char cb[BUFSIZ+1];
- X char tmpf[LPNMAX];
- X long tu;
- X long bu;
- X int nu;
- X long stat = 0;
- X
- X clnp = cleanup;
- X signal( SIGHUP, clnp );
- X signal( SIGQUIT, clnp );
- X signal( SIGINT, clnp );
- X signal( SIGILL, clnp );
- X signal( SIGIOT, clnp );
- X signal( SIGEMT, clnp );
- X signal( SIGFPE, clnp );
- X signal( SIGBUS, clnp );
- X signal( SIGSEGV, clnp );
- X signal( SIGSYS, clnp );
- X signal( SIGTERM, clnp );
- X
- X umask( 022 );
- X sprintf( tmpf, "%s/%s", pegdir, TMPLATE );
- X mktemp( tmpf );
- X if(( tfp = fopen( tmpf, "w+" )) == NULL ) {
- X sprintf( tb,
- X "could not open pegboard copy file \"%s\"", tmpf );
- X faterr( tb ); /* Exits. */
- X }
- X
- X umask( 0111 );
- X if(( pegfd = open( pegfnm, O_RDWR )) == (-1)) {
- X sprintf( tb,
- X "could not open pegboard file \"%s\"", pegfnm );
- X faterr( tb ); /* Exits. */
- X }
- X
- X pblock( pegfd );
- X if( ! x ) {
- X /*
- X If pegging out and end of day then round off the time to
- X the start time for that day (as found in rc)
- X */
- X if( eod ) {
- X int dbdy;
- X int dy;
- X
- X stat = 0;
- X /*
- X Skip over any days that are not found in rc file.
- X Check elements of due back times array, starting
- X from the day in duback, up to a week from then
- X */
- X dbdy = dy = localtime( &duback )->tm_wday;
- X while( starts[dbdy] == ( -1 )) {
- X /*
- X If wrapped around then no start times are spec'd
- X */
- X if( dy == ( dbdy = ( dbdy == 6 ? 0 : ++dbdy ))) {
- X stat = 0;
- X break;
- X }
- X /*
- X If the day not spec'd then goto next day
- X */
- X stat += 86400;
- X }
- X /*
- X Add in offset to next day with start time, if any
- X Round to the day boundary and add the start itme for that
- X day, if any
- X */
- X duback += stat;
- X dround( &duback );
- X duback +=
- X (( stat = starts[ localtime( &duback )->tm_wday ]) == ( -1 )
- X ? 0L : stat );
- X }
- X /*
- X If admin is updating for someone else then keep the old
- X logout time and comment, unless "-r" given on command line.
- X */
- X if( admupd ) {
- X /*
- X Admin update
- X */
- X while(( igets( tb, BUFSIZ, pegfd )) != NULL ) {
- X cb[0] = '\0';
- X sscanf( tb, "%d %ld %ld %64[ -~\t]", &nu, &tu, &bu, cb );
- X if( ru != nu )
- X continue;
- X break; /* Found mortals entry */
- X }
- X if( lseek( pegfd, 0L, 0 ) == ( -1 )) {
- X sprintf( tb, "could not rewind \"%s\"", pegfnm );
- X faterr( tb ); /* Exits. */
- X }
- X if( ! *comment )
- X strcpy( comment, cb );
- X }
- X /*
- X If normal run then put the current time in the logout field
- X */
- X else
- X time( &tu );
- X if( duback < tu ) {
- X fprintf( stderr, "%s: too late\n", invkst );
- X cleanup( 1 );
- X }
- X /*
- X If there is a discrepancy due to daylight savings time between
- X now and the target date then fix it.
- X */
- X if( today.tm_isdst ^ localtime( &duback )->tm_isdst )
- X duback = ( today.tm_isdst ? duback + 3600 : duback - 3600 );
- X fprintf( tfp, "%d %ld %ld %.64s\n", ru, tu, duback,
- X comment == NULL ? "" : comment );
- X }
- X while(( igets( tb, BUFSIZ, pegfd )) != NULL ) {
- X cb[0] = '\0';
- X sscanf( tb, "%d %ld %ld %64[ -~\t]", &nu, &tu, &bu, cb );
- X if( ru != nu )
- X fprintf( tfp, "%d %ld %ld %s\n", nu, tu, bu, cb );
- X }
- X
- X if( fseek( tfp, (long)0, 0 )) {
- X sprintf( tb, "could not rewind \"%s\"", tmpf );
- X faterr( tb ); /* Exits. */
- X }
- X sprintf( cb,
- X "cannot update pegboard \"%s\", there is a copy in \"%s\"",
- X pegfnm, tmpf );
- X /*
- X Clobber the old pegboard
- X */
- X if((( clfd = open( pegfnm, O_WRONLY|O_TRUNC )) == (-1))
- X || ( close( clfd )))
- X faterr( cb ); /* Exits. */
- X /*
- X Copy tmp file back onto pegboard
- X */
- X if( lseek( pegfd, 0L, 0 ) == ( -1 ))
- X faterr( cb );
- X while( fgets( tb, BUFSIZ, tfp ) != NULL ) {
- X if( write( pegfd, tb, (unsigned)strlen( tb )) == ( -1 ))
- X faterr( cb ); /* Exits. */
- X }
- X
- X pbunlock( pegfd );
- X
- X if( close( pegfd ))
- X faterr( cb ); /* Exits. */
- X /*
- X Clobber tmp file, ensure pegboard available to all
- X */
- X if( unlink( tmpf ))
- X fprintf( stderr, "%s: could not remove file \"%s\" (errno %d)\n",
- X invkst, tmpf, errno );
- X chmod( pegfnm, 0666 ); /* rw-rw-rw- */
- X
- X if(( ! quiet ) && ( ! x ))
- X showtime( &duback );
- X return( 0 );
- X}
- X
- X/*
- X Read a shorter than n \n terminated line from a fd
- X*/
- Xchar *igets( s, n, fd )
- Xchar *s;
- Xint n;
- Xint fd;
- X{
- X char *t;
- X
- X t = s;
- X while( --n ) {
- X switch( read( fd, t, 1 )) {
- X case 1:
- X if( *t++ == '\n' ) { /* EOL? */
- X *t = '\0';
- X return( s );
- X }
- X continue;
- X
- X case 0: /* EOF? */
- X return( NULL );
- X
- X case -1:
- X default:
- X sprintf( s,
- X "error %d reading file descriptor %d",
- X errno, fd );
- X faterr( s ); /* Exits. */
- X }
- X }
- X /*
- X > n bytes up to next \n in file, return what's collected so far
- X */
- X *t = '\0';
- X return( s );
- X}
- X
- Xrcinit( )
- X{
- X extern char *pegfnm;
- X extern char *pegdir;
- X FILE *rcfp;
- X char tb[BUFSIZ];
- X
- X /*
- X SUN - SAT must use the 0 - 6 slots!
- X */
- X# define SUN 0
- X# define MON 1
- X# define TUE 2
- X# define WED 3
- X# define THU 4
- X# define FRI 5
- X# define SAT 6
- X# define NOPEGTK 7
- X# define PEGDIR 8
- X
- X static char *srctkns[] = {
- X "sun", "mon", "tue", "wed", "thu", "fri", "sat",
- X "nounpeg", "pegdir",
- X "" };
- X static char *urctkns[] = {
- X "sun", "mon", "tue", "wed", "thu", "fri", "sat",
- X "" };
- X
- X /*
- X Read the system rc file, consider it mandatory
- X */
- X if(( rcfp = fopen( RCFNAM, "r" )) == NULL ) {
- X sprintf( tb, "cannot open \"%s\"", RCFNAM );
- X faterr( tb ); /* Exits. */
- X }
- X finit( rcfp, srctkns );
- X fclose( rcfp );
- X
- X /*
- X Read the users rc file, but ignore if it does not exist
- X */
- X sprintf( tb, "%s/%s", getenv( HOMENV ), PEGRCFN );
- X if(( rcfp = fopen( tb, "r" )) != NULL )
- X finit( rcfp, urctkns );
- X fclose( rcfp );
- X /*
- X If we did not pick up names in the system default file
- X then assign the defaults
- X */
- X if( pegfnm == NULL )
- X pegfnm = PEGBOARD;
- X if( pegdir == NULL )
- X pegdir = PBDIR;
- X return( 0 );
- X}
- X
- Xvoid finit( rcfp, tkns )
- XFILE *rcfp;
- Xchar *tkns[];
- X{
- X# define TSEPCH " \t=\n"
- X char tb[BUFSIZ*2];
- X int i;
- X char *ttynm;
- X char *tkargp;
- X extern char *pegfnm;
- X extern char *pegdir;
- X extern int chk; /* Set for check runs */
- X extern int normpeg;
- X extern long starts[];
- X
- X ttynm = ttyname( 0 );
- X
- X while(fgets( tb, BUFSIZ, rcfp ) != NULL ) {
- X tkargp = strtok( tb, TSEPCH );
- X lows( tkargp );
- X for( i = 0 ; *tkns[i] ; i++ ) {
- X if( ! strncmp( tb, tkns[i], strlen( tkns[i] ))) {
- X switch( i ) {
- X /*
- X Default start times
- X */
- X case SUN:
- X case MON:
- X case TUE:
- X case WED:
- X case THU:
- X case FRI:
- X case SAT:
- X starts[i] = fixstrt( strtok( 0, TSEPCH ));
- X continue;
- X /*
- X Is terminal (modem most likely) on the no peg out list?
- X */
- X case NOPEGTK:
- X tkargp = strtok( 0, TSEPCH );
- X if((( ! strcmp( ttynm, tkargp )))
- X && ( ! chk ))
- X normpeg++;
- X continue;
- X /*
- X Pegboard directory? Get pegboard filename
- X */
- X case PEGDIR:
- X tkargp = strtok( 0, TSEPCH );
- X pegfnm =
- X malloc((unsigned)
- X strlen( tkargp ) + strlen( PBFNM ) + 2 );
- X sprintf( pegfnm, "%s/%s", tkargp, PBFNM );
- X continue;
- X
- X default:
- X sprintf( tb,
- X "init file \"%s\" garbled", RCFNAM );
- X faterr( tb ); /* Exits. */
- X } /* End of switch */
- X } /* End of if */
- X } /* End of for */
- X } /* End of while */
- X}
- X
- Xpblock( fd )
- Xint fd;
- X{
- X extern int errno;
- X struct flock lk;
- X
- X lk.l_type = F_WRLCK;
- X lk.l_whence = 0;
- X lk.l_start = 0L;
- X lk.l_len = 0L;
- X
- X if( fcntl( fd, F_SETLK, &lk ) == (-1)) {
- X char msg[BUFSIZ];
- X sprintf( msg, "fcntl lock failed on pegboard, errno %d", errno );
- X faterr( msg ); /* Exits. */
- X }
- X return( 0 );
- X}
- X
- Xpbunlock( fd )
- Xint fd;
- X{
- X extern char *invkst;
- X struct flock lk;
- X
- X lk.l_type = F_UNLCK;
- X lk.l_whence = 0;
- X lk.l_start = 0L;
- X lk.l_len = 0L;
- X
- X if( fcntl( fd, F_SETLK, &lk ) == (-1))
- X fprintf( stderr, "%s: fcntl unlock failed on pegboard", invkst );
- X return( 0 );
- X}
- X
- Xlong fixstrt( s )
- Xchar *s;
- X{
- X int h;
- X int m;
- X
- X if( ! isdigit( *s ))
- X return( -1L );
- X sscanf( s, "%d:%d", &h, &m );
- X
- X return((long)(( h * 3600 ) + ( m * 60 )));
- X}
- X
- Xchkpeg( u )
- Xunsigned short u;
- X{
- X FILE *pegfd;
- X char b[30];
- X int v;
- X
- X if(( pegfd = fopen( pegfnm, "r" )) == NULL )
- X return( -1 );
- X
- X while( fgets( b, 30, pegfd ) != NULL ) {
- X sscanf( b, "%d", &v );
- X if( v == u ) {
- X if( close( pegfd ))
- X faterr( "system error closing pegboard" );
- X return( 0 );
- X }
- X }
- X if( close( pegfd ))
- X faterr( "system error closing pegboard" );
- X return( 1 );
- X}
- X
- Xvoid faterr( m )
- Xchar *m;
- X{
- X extern char *invkst;
- X
- X fprintf( stderr, "%s: %s\n", invkst, m );
- X perror( "last system error" );
- X cleanup( errno );
- X}
- X
- Xcleanup( s )
- Xint s;
- X{
- X exit( s );
- X}
- END_OF_FILE
- if test 10884 -ne `wc -c <'pegio.c'`; then
- echo shar: \"'pegio.c'\" unpacked with wrong size!
- fi
- # end of 'pegio.c'
- fi
- if test -f 'tfix.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tfix.c'\"
- else
- echo shar: Extracting \"'tfix.c'\" \(3793 characters\)
- sed "s/^X//" >'tfix.c' <<'END_OF_FILE'
- X/*
- X tfix.c
- X*/
- X
- X#include "peg.h"
- X
- X/*
- X Convert two longs representing a target hour and minute into seconds
- X from the day boundary, and update the running count for that time.
- X
- X*/
- Xlong fixhm( h, m )
- Xlong h; /* Hours */
- Xlong m; /* Minutes */
- X{
- X extern struct tm today;
- X extern long duback;
- X
- X while( m >= 60 ) {
- X h += 1;
- X m -= 60;
- X }
- X /*
- X If the specified time has gone by assume invoker means tomorrow
- X */
- X if(( today.tm_year == localtime( &duback )->tm_year )
- X && ( today.tm_yday == localtime( &duback )->tm_yday )
- X && ( today.tm_hour > h ))
- X h += 24;
- X
- X dround( &duback );
- X return(( duback += (( m * 60 ) + ( h * 3600 ))));
- X}
- X
- Xvoid dround( t )
- Xlong *t;
- X{
- X while( (*t) % 3600 ) /* Round back to hour */
- X (*t)--;
- X while( localtime( t )->tm_hour ) /* Then to the day */
- X (*t) -= 3600;
- X}
- X
- X/*
- X Convert 3 arguments (yy/mm/dd) into an offset in seconds from
- X the current date, and update the running count.
- X
- X Bugs: Ignores leap seconds
- X*/
- Xlong fixymd( y, m, d )
- Xlong y; /* Year */
- Xlong m; /* Month */
- Xlong d; /* Day */
- X{
- X extern struct tm today;
- X extern long duback;
- X static int modays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
- X 30, 31 };
- X int i;
- X
- X /*
- X Deal with months from 0-11 (caller passes 1-12), check against bounds.
- X */
- X if( --m < 0 || m > 11 )
- X specerr( "illegal month" );
- X /*
- X Check if date gone by
- X */
- X if( y < today.tm_year
- X || ( y == today.tm_year && (( m == today.tm_mon && d < today.tm_mday ) ||
- X ( m < today.tm_mon))))
- X specerr( "illegal date" );
- X /*
- X Check day against bounds
- X */
- X if(((( ! ( y % 4 )) && ( y % 100 )) || ( ! ( y % 400 ))))
- X modays[1] = 29;
- X if( d < 0 || d > modays[m] )
- X specerr( "illegal day" );
- X /*
- X Convert mm/yy for target year into tm_yday
- X */
- X if((( ! ( y % 4 )) && ( y % 100 ))
- X || ( ! ( y % 400 )))
- X modays[1] = 29;
- X else
- X modays[1] = 28;
- X for( i = 0 ; i < m ; i++ )
- X d += modays[i];
- X d -= today.tm_yday + 1 ;
- X
- X /*
- X Count number of leap years between next year and the
- X target year.
- X */
- X for( i = today.tm_year + 1 ; i < y ; i++ ) {
- X if((( ! ( i % 4 )) && ( i % 100 )) || ( ! ( i % 400 )))
- X ++d;
- X }
- X /*
- X Get the years offset
- X */
- X y=(long)abs((int)( today.tm_year - y ));
- X
- X /*
- X If this is a leap year and the target year is not this year
- X then we need another day...
- X */
- X if(((( ! ( today.tm_year % 4 )) &&
- X ( today.tm_year % 100 )) || ( ! ( today.tm_year % 400 ))) && y )
- X ++d;
- X /*
- X Convert it to days then seconds
- X */
- X return( fixday((long)( y * 365 ) + d ));
- X}
- X
- X/*
- X Return some number of days converted to seconds, added to the
- X running total in duback.
- X
- X Externals: duback
- X Returns: duback
- X*/
- Xlong fixday( d )
- Xlong d;
- X{
- X extern long duback;
- X
- X return( duback += ( d * 86400 ));
- X}
- X
- X/*
- X Check see if string starts with a valid month name. Return
- X 0 if not, 1-12 if so.
- X*/
- Xismonth( s )
- Xchar *s;
- X{
- X extern int eod;
- X static char *months[] = { "jan", "feb", "mar", "apr", "may", "jun",
- X "jul", "aug", "sep", "oct", "nov", "dec", "" };
- X int i;
- X
- X for( i = 0 ; *months[i] ; i++ ) {
- X if( ! strncmp( s, months[i], 3 ))
- X return( ++i );
- X }
- X return( 0 );
- X}
- X
- X/*
- X Check see if string starts with a valid day name. Return
- X -1 if not, day of week (0 = sun) if so.
- X*/
- Xisday( s )
- Xchar * s;
- X{
- X static char *days[] = { "sun", "mon", "tue", "wed", "thu",
- X "fri", "sat", "" };
- X int i;
- X
- X for( i = 0 ; *days[i] ; i++ ) {
- X if( ! strncmp( s, days[i], 3 ))
- X return( i );
- X }
- X return( -1 );
- X}
- X
- Xvoid copytime( t, n )
- Xstruct tm *t;
- Xstruct tm *n;
- X{
- X n->tm_sec = t->tm_sec;
- X n->tm_min = t->tm_min;
- X n->tm_hour = t->tm_hour;
- X n->tm_mday = t->tm_mday;
- X n->tm_mon = t->tm_mon;
- X n->tm_year = t->tm_year;
- X n->tm_wday = t->tm_wday;
- X n->tm_yday = t->tm_yday;
- X n->tm_isdst = t->tm_isdst;
- X#ifndef BSD
- X n->tm_tzadj = t->tm_tzadj;
- X strcpy( n->tm_name, t->tm_name );
- X#endif /* BSD */
- X}
- X
- Xshowtime( t )
- Xlong *t;
- X{
- X printf( "%s", ctime( t ) );
- X}
- X
- END_OF_FILE
- if test 3793 -ne `wc -c <'tfix.c'`; then
- echo shar: \"'tfix.c'\" unpacked with wrong size!
- fi
- # end of 'tfix.c'
- fi
- echo shar: End of shell archive.
- exit 0
-